#!/usr/bin/perl -Tw
BEGIN{
	push @INC, "./libs"
}
use strict;
use cookie;
use passwd;
use ACM;
use Log::Log4perl qw(get_logger :levels);

# set up logging
my $logger = get_logger("suid_core");
$logger->level($DEBUG);
my $appender = Log::Log4perl::Appender->new(	"Log::Dispatch::File", 
						filename => "wrapper.log",
						mode => "append" );
$logger->add_appender($appender);
my $layout = Log::Log4perl::Layout::PatternLayout->new("%d %p %M %m%n");
$appender->layout($layout);

# main part
# - check a cookie
# - check a password
# - get a file
# - log a user out
my $cmd = $ARGV[0] or syntax();

if($cmd eq "cookie") {
	my $cookie = $ARGV[1];
	my $ip = $ARGV[2];
	$logger->debug("Checking $cookie $ip");
	print check_cred($cookie, $ip);
} elsif ($cmd eq "passwd") {
	my $uid = $ARGV[1];
	my $pass = $ARGV[2];
	my $ip = $ARGV[3];
	$logger->debug("Checking $uid $ip");
	print check_passwd($uid, $pass, $ip);
} elsif ($cmd eq "file") {
	my $cookie = $ARGV[1];;
	my $filename = $ARGV[2];
	my $ip = $ARGV[3];
	$logger->debug("Getting $filename for $cookie $ip");
	print get_file($cookie, $filename, $ip);
} elsif ($cmd eq "logout") {
	my $cookie = $ARGV[1];
	my $ip = $ARGV[2];
	$logger->debug("Logging out $cookie $ip");
	print logout($cookie, $ip);
} else {
	$logger->debug("Bad args: @ARGV");
}

return;

# get the specified file (if allowed)
sub get_file {
	my $cookie = shift;
	my $filename = shift;
	my $ip = shift;
	my $ret = 0;
	my $uid = check_cred($cookie, $ip);
	my $group = passwd::group($uid);
	
	if(!($uid && $group)){
		$logger->error("Access denied - bad credentials $uid/$group $ip");
		return "Permission denied.\n";
	}

	if(ACM::check($group, $filename)) {
		$logger->debug("Success for $filename ($group) $ip");
		open(FD, "<".$filename);
		my @file = <FD>;
		close FD;
		my $file = join('', @file);
		$file =~ s/\n/<br>/g;
		return $file;
	} else {
		$logger->error("Access denied for $uid/$group $filename $ip");
		return "Permission denied.";
	}
}


sub check_passwd {
	my $uid = shift;
	my $pass = shift;
	my $ip = shift;
	
	if(!($uid && $pass)) {
		$logger->error("Malformed credentials");
		die "Malformed credentials";
	}	
	
	if(passwd::check($uid, $pass)) {
		cookie::remove_tuple($uid);
		$logger->debug("Cookie set for $uid $ip");
		return cookie::set($uid, $ip);
	} else {
		$logger->error("Bad credentials for $uid $ip");
		die "Bad credentials for $uid";
	}
}


sub check_cred {
	my $cookie = shift;
	my $ip = shift;
	my ($c_hash, $c_uid) = split(/\|/, $cookie);
	if(!($c_uid && $c_hash)) {
		$logger->error("Malformed cookie");
		return ();
	}
	my $group;
	if(cookie::check_tuple($c_hash, $c_uid, $ip)) {
		$logger->debug("Cookie accepted for $c_uid $ip");
		return $c_uid;
	} else {
		$logger->error("Bad cookie for $c_uid $ip");
		return ();
	}
}

sub logout {
	my $cookie = shift;
	my $ip = shift;
	my $uid = check_cred($cookie, $ip);
	if(!$uid) {
		$logger->debug("Logging out $cookie $ip failed");
		return "Permission denied.\n";	
	}

	$logger->debug("Logging out $cookie");
	cookie::remove_tuple($uid);
	return $uid;

}

sub syntax {
	$logger->warn("Called without args");
 print <<FOO;
 -------
 syntax:
 -------
* $0 cookie {the cookie} - check cookie
* $0 passwd {user id} {password} -  check password
* $0 file {cookie} {filename} - get the file
* $0 logout {cookie} - log the user out
FOO
	exit;
}
